/*
 * @Description:
 * @Author: wsy
 * @Date: 2022-01-16 03:06:51
 * @LastEditTime: 2022-01-16 03:24:03
 * @LastEditors: wsy
 */
let Vue;
class VueRouter {
  constructor(options) {
    this.$options = options;
    this.routeMap = new Map();
    const initial = window.location.hash.slice(1) || '/';

    Vue.util.defineReactive(this, 'current', initial);

    this.init();
  }
  static install(_Vue) {
    if (this.install.installed) {
      return;
    }
    this.install.installed = true;
    Vue = _Vue;
    Vue.mixin({
      beforeCreate() {
        if (this.$options.router) {
          Vue.prototype.$router = this.$options.router;
        }
      },
    });
  }
  init() {
    this.createRouteMap();
    this.initComponent();
    this.initEvent();
  }
  createRouteMap() {
    this.$options.routes.forEach(({ path, component }) => {
      this.routeMap.set(path, component);
    });
  }
  initComponent() {
    const self = this;
    Vue.component('router-link', {
      props: {
        to: {
          type: String,
          required: true,
        },
      },
      render(h) {
        return h(
          'a',
          {
            attrs: {
              href: '#' + this.to,
            },
          },
          this.$slots.default
        );
      },
    });
    Vue.component('router-view', {
      render(h) {
        const component = self.routeMap.get(this.$router.current);
        return h(component);
      },
    });
  }
  initEvent() {
    window.addEventListener('hashchange', () => {
      this.current = window.location.hash.slice(1);
    });
  }
}

export default VueRouter;
